home *** CD-ROM | disk | FTP | other *** search
- /************************************************
- TMS320C26 DSK RS232 I/O AND OTHER ASSORTED FUNCTIONS
- Keith Larson
- DSP Applications
- Texas Instruments Inc
- (C)opyright 1992, 1993
- ************************************************/
- #include <stdlib.h>
- #include <bios.h>
- #include <ctype.h>
- #include <conio.h>
- #include <stdio.h>
- #include <string.h>
- #include <graphics.h>
- #include <dos.h>
-
- #include "DSK_DRV2.H"
-
- extern int port_no;
- extern int baud, userbaud;
-
- int start_graphics(void)
- {
- int gdriver = EGA, gmode = EGAHI, errorcode;
- // registerbgidriver(EGAVGA_driver);
- initgraph(&gdriver, &gmode, "");
- errorcode = graphresult();
- if (errorcode != grOk)
- {
- printf("Graphics error: %s\n", grapherrormsg(errorcode));
- printf("Press any key to halt:");
- getch();
- exit(1);
- }
- setviewport(100, 50, 355, 305, 1);
- return 0;
- }
-
- void GRAPH(void)
- {
- int x, y, page=0;
- char ch;
- start_graphics();
- for(;;)
- {
- ch = crcv(port_no);
- y = ch;
- if(y == 0)
- {
- setvisualpage(page);
- page ^= 1;
- setactivepage(page);
- cleardevice();
- rectangle(0,0,255,255);
- moveto(0,255);
- x = 0;
- }
- y = 128 - y;
- lineto(x,y);
- x++;
- if(kbhit())
- {
- closegraph();
- clrscr();
- printf(">>>>>> DSKL is now in command mode\n");
- return;
- }
- }
- }
-
- void execute(int addr)
- {
- cxmit(SYNCH,port_no);
- cxmit(BRANCH,port_no); // Select BRANCH to address
- ixmit(addr,port_no);
- }
-
- void usage(void)
- {
- printf("DSKL: DOS Command line Usage \n");
- printf(" \n");
- printf("C:\DSKTOOLS\DSKL [A][Cx][Bxxxxx][I] \n");
- printf(" | | | | \n");
- printf(" | | | +--Inverse DTR (Reset logic) \n");
- printf(" | | +---------Baud xxxxx (9600,19200,38400)\n");
- printf(" | +-------------Initialy load to COM1, COM2 \n");
- printf(" +-----------------Autotest \n");
- printf(" \n");
- printf("NOTE: \n");
- printf(" Up & Down adjusts baud \n");
- printf(" Left & Right changes commport \n");
- printf(" Q will quit during bootload \n");
- printf(" \n");
- }
-
- /*********************************************************************/
- /* unsigned int load_file(int arg, char *FILE) */
- /* if arg = 0; MDM_COM2.DSK is bootloaded and verified (echo data) */
- /* 1; INFILE.DSK is requested and loaded via MDM_COM2.DSK */
- /* 2; FILE is loaded via MDM_COM2.DSK */
- /* */
- /* Returns the file ENTRY point */
- /*********************************************************************/
- unsigned int load_file(int arg, char *strg)
- {
- char fbuf[32], key;
- int TEST;
- uint ENTRY, i, tries = 1;
- ulong rate;
- strcpy(fbuf,"MDM_COM2.DSK");
-
- i = 2 -((port_no-0x2f8) >> 8);
- switch(arg)
- {
- case 3: printf(" FILE TO BOOT >> ");
- strupr(gets(fbuf));
- if(strstr(fbuf,".") == NULL) strcat(fbuf,".DSK");
- arg = 0;
-
- case 0: TEST = 0;
- while(TEST != 0x1111)
- {
- clrscr();
- i = 2 -((port_no-0x2f8) >> 8);
- rate = 115200/baud;
- printf("[Q]uit exits program\n\n");
- printf("%s >Boot:%d Com:%d Baud:%lu\n",fbuf,tries++,i,rate);
- baud = baud << 2; // kernal loads at 1/4 baud
- ENTRY = load_DSK(arg,fbuf);
- baud = baud >> 2; // set original baud 4x
- initcom(port_no,baud);
- if(kbhit())
- {
- i = bioskey(0);
- key = i & 0xff;
- if((key == 'Q') || (key == 'q')) exit(0);
- if(i==0x4B00) port_no = 0x3f8;
- if(i==0x4D00) port_no = 0x2f8;
- if(i==0x4800) baud = baud >> 1;
- if(i==0x5000) baud = baud << 1;
- if(baud == 0) baud = 1;
- if(baud > 96) baud = 96;
- }
- TEST = 0x1111;
- write_data(0x70,1,&TEST); // write and verify a
- TEST = 0; // known value to the DSK
- read_data (0x70,1,&TEST);
- }
- TEST = 0;
- write_data(0x70,1,&TEST);
- printf("%s Succesfully loaded\n",fbuf);
- break;
-
- case 1: printf(" FILE TO LOAD >> ");
- strupr(gets(fbuf));
- if(strstr(fbuf,".") == NULL) strcat(fbuf,".DSK");
- printf("Loading %s to DSK Com:%d\n",fbuf,i);
- ENTRY = load_DSK(arg,fbuf);
- break;
-
- case 2: arg = 1;
- strupr(strg);
- printf("Loading %s to DSK Com:%d\n",strg,i);
- ENTRY = load_DSK(arg,strg);
- break;
-
- default: break;
- }
- printf("Entry:%04x\n",ENTRY);
- printf("Hit >enter< to continue\n");
- return(ENTRY);
- }
- /*********************************************************************/
- /* unsigned int load_DSK(FILE *in_file, int pass) */
- /* if pass = 0; in_file is loaded via the C26 bootloader */
- /* pass = 1; in_file is loaded via MDM_COM2 (must be loaded!) */
- /* */
- /* Returns file ENTRY point */
- /*********************************************************************/
- unsigned int load_DSK(int pass, char *filename)
- {
- FILE *in_file;
- char buf[512],*ptr;
- unsigned int i, ENTRY,load;
- int ADDR, CMD;
- int boot_csum, boot_len=0;
-
- if ((in_file = fopen(filename, "r")) == NULL) // Is file available?
- {
- printf("Could not open %s! Exiting program\n",filename);
- exit(0);
- }
-
- if(pass == 0)
- {
- initcom(port_no,baud);
- reset(port_no);
- }
- pass &=0x1;
- load = pass;
- fseek(in_file,0,SEEK_SET); // reset to first line
- fscanf(in_file,"%s",&buf); // Read first line
- if(buf[0] != 'K')
- {
- printf("Not a valid DSK file\n");
- getch();
- fclose(in_file);
- return(0);
- }
- for(;pass<2;pass++)
- {
- boot_csum= 0;
- fseek(in_file,0,SEEK_SET); // reset to first line
- fscanf(in_file,"%s",&buf); // Read first line
- if((pass==1) && !load)
- {
- boot_len--;
- ixmit((boot_len & 0x700)|0x8FF,port_no); // STATUS and BAUD_DTCT
- ixmit(((boot_len & 0xFF)<<8)|0x80,port_no);// LENGTH and INT
- boot_len=0;
- }
- while(!feof(in_file))
- {
- fscanf(in_file,"%s\r\n",buf); // Read a line
- ptr = buf;
- switch(buf[0])
- {
- case '1': ENTRY = read4(ptr); // 1=entry point
- break;
- case '9': ADDR = read4(ptr); // 9=address
- if(load)
- {
- while(buf[0] != '7')
- {
- if(buf[0] == 'M')
- CMD = UL_DATA;
- else
- {
- if(buf[0] == 'B')
- CMD = UL_PROG;
- else
- {
- printf("ERROR READING FILE\n");
- exit(0);
- }
- }
- i = read4(ptr);
- cxmit(CMD,port_no); // Select PROG/DATA
- ixmit(ADDR++,port_no); // where to put it
- ixmit(0,port_no); // length 1
- ixmit(i,port_no); // send the value
- printf("\r%d words",boot_len++);
- }
- }
- else /* boot */
- {
- while(buf[0] != '7')
- {
- i = read4(ptr);
- if(pass==1)
- ixmit(i,port_no);
- printf("\r%d words",boot_len);
- boot_len++;
- boot_csum += i;
- }
- }
- break;
- case ':': break;
- default : printf("Error reading file\n");
- ENTRY=0;
- break;
- }
- if(buf[0]==':') break;
- }
- if((pass==1) && !load)
- {
- ixmit(boot_csum,port_no); // CHECKSUM at EO 2nd pass
- cxmit(0xff,port_no); // same for synch
- }
- }
- printf("\n");
- fclose(in_file); // close file when done
- return(ENTRY);
- }
-
- unsigned int read4(char *ptr)
- {
- char val[200], *nptr;
- unsigned int i;
- strcpy(val,"0x");
- strcat(val,ptr+1);
- val[6] = 0;
- i = strtol(val,&nptr,16);
- strcpy(ptr,ptr+5);
- return(i);
- }
-
- /*********************************************************************/
- /* write_data(int address, int length, int *data); */
- /* if MDM_COM2 is loaded, *data is transferred to the DSK */
- /*********************************************************************/
- void write_data(int addr, int length, int *data)
- {
- cxmit(UL_DATA,port_no); // Select DATA download to DSK
- ixmit(addr,port_no); // where to put it
- ixmit(length-1,port_no); // length
- for(;length>0;length--) //
- ixmit(*data++,port_no); // send the value
- }
- /*********************************************************************/
- /* rcv_char_buf(int length, char *data); SPECIAL TO DSK_SA26 */
- /* This routine is designed to receive a block of BYTES not int's */
- /* from the DSK. Normaly the MDM_COM2 kenral is used to transfer */
- /* blocks of integers which are the native format for the C26 DSP. */
- /* In this case rcv_char_buf is used to speed up transfers since */
- /* the result in this application is packed bytes of data which */
- /* have also been bit-reversed. A host would be inefficient in */
- /* this task and is avoided for the sake of speed. */
- /* ALSO PLEASE NOTE THIS MAY CHANGE IN FUTURE ANALYZERS! */
- /*********************************************************************/
- void rcv_char_buf(int length,char *ptr)
- {
- int x;
- asm cli // disable x86 INT's
- cxmit(0,port_no); //start data sweep
- for(x=0;x<length;x++) //
- *ptr++ = Bcrcv(port_no); // receive BYTES not INTS
- asm sti // enable x86 INT's
- }
- /*********************************************************************/
- /* read_data(int address, int length, int *data); */
- /* if MDM_COM2 is loaded, *data is filled with data from the DSK */
- /*********************************************************************/
- void read_data(int addr, int length, int *data)
- {
- int i;
- cxmit(DL_DATA,port_no); // Select DATA upload from DSK
- ixmit(addr,port_no); // where to get it
- ixmit(length-1,port_no); // length
- for(;length>0;length--) //
- {
- // *data++ = ircv(port_no); // receive the value
- i = crcv(port_no);
- i+= (crcv(port_no)<<8);
- *data++ = i;
- }
- cxmit(SYNCH ,port_no); // Extra SYNCH to get back to command mode
- }
-
- /*********************************************************************/
- /* Bread_data(int address, int length, int *data); */
- /* Fast version of read_data where handshaking each byte is avoided*/
- /* NOTE: If the host receives an interrupt etc... DANGEROUS!!! */
- /*********************************************************************/
- void Bread_data(int addr, int length, int *data)
- {
- int i;
- asm cli // turn off x86 interrupts
- cxmit(BDL_DATA,port_no); // Select DATA upload from DSK
- ixmit(addr,port_no); // where to get it
- ixmit(length-1,port_no); // length
- for(;length>0;length--) // write this routine fast!
- {
- i = Bcrcv(port_no);
- i+= (Bcrcv(port_no)<<8);
- *data++ = i;
- }
- cxmit(SYNCH ,port_no); // Extra SYNCH to get back to command mode
- asm sti // turn on x86 interrupts
- }
-
- void initcom(int port_no,int baud)
- {
- asm mov DX,word ptr port_no //
- asm add DX,3 //
- asm mov AL,087h // set access to BAUD divisor
- asm out DX,AL //
- asm sub DX,3 //
- asm mov AX,word ptr baud // Set baud rate LSB
- asm out DX,AL //
- asm add DX,1 //
- asm mov AL,byte ptr baud // Set baud rate MSB
- asm xchg AL,AH //
- asm out DX,AL //
- asm sub DX,1 //
- asm add DX,3 //
- asm mov AL,07h // CLR BAUD access... N-8-2
- asm out DX,AL //
- asm out DX,AL // N-8-2
- }
-
- void reset(int port_no)
- {
- DTR_hi(port_no);
- DTR_lo(port_no);
- DTR_hi(port_no);
- }
- void DTR_lo(int port_no)
- {
- asm mov DX,word ptr port_no //modem control register 02FCh 03FCh
- asm add DX,4 //
- asm mov AL,0xA //RTS=1, DTR=0
- asm out DX,AL //
- delay(1);
- }
- void DTR_hi(int port_no)
- {
- asm mov DX,word ptr port_no //modem control register
- asm add DX,4 //
- asm mov AL,0xB //RTS=1, DTR=0
- asm out DX,AL //
- delay(1);
- }
-
- void ixmit(int i,int port_no)
- {
- cxmit(i,port_no);
- cxmit(i>>8,port_no);
- }
- /****************************************************************/
- /* ircv and Bircv each receive two bytes making an int. */
- /* NOTE: Birecv uses Bcrcv() which does not use hanshaking. */
- /* Use Bircv with caution as system ints etc.. cause pblms*/
- /****************************************************************/
- unsigned int ircv(int port_no)
- {
- int i;
- i = crcv(port_no);
- i+= (crcv(port_no)<<8);
- return(i);
- }
- unsigned int Bircv(int port_no)
- {
- int i;
- i = Bcrcv(port_no);
- i+= (Bcrcv(port_no)<<8);
- return(i);
- }
- /****************************************************************/
- /* cxmit transmits a charcter */
- /****************************************************************/
- void cxmit(char c, int port_no)
- {
- asm mov DX,word ptr port_no // load base addr 0x2FD 0x3FD
- asm mov AL,byte ptr c //
- asm out DX,AL // transmit byte... channel should be clear
- asm add DX,5 //
- xempty2: //
- asm sub DX,5 //
- asm in AL,DX // clr rcv flag (XF sumcheck, noise etc..)
- asm add DX,5 // check LINE_STATUS 0x2FD 0x3FD (+5)
- asm in AL,DX //
- asm and AL,060h // wait for DXR and XSR to empty
- asm cmp AL,060h //
- asm jne xempty2 //
- }
- /****************************************************************/
- /* printerr is a global error for RS232 comm errors */
- /****************************************************************/
- int x, y, errnum=0;
- void printerr(void)
- {
- x = wherex(); // If a timeout occurs, a TIMEOUT message
- y = wherey(); // can be written to the screen.
- gotoxy(1,25); //
- printf("RCV T/O %d",errnum++);// Error MSG to bottom of screen
- gotoxy(x,y); //
- }
- /****************************************************************/
- /* crcv receives a charcter using handshake protocol (safest!) */
- /****************************************************************/
- unsigned char crcv(int port_no)
- {
- unsigned char c;
- asm mov DX,word ptr port_no // load base addr 0x2FD 0x3FD
- asm mov AL,0 // synch value
- asm out DX,AL //
- asm add DX,5 // check LINE_STATUS 0x2FD 0x3FD (+5)
- asm mov BX,4000 // 836 loops is marginal at 4800 baud.
- chkst: // with 33MHz 486
- asm sub bx,1 //
- asm jz timerr //
- asm in AL,DX //
- asm and AL,061h //
- asm cmp AL,061h //
- asm jne chkst // wait for DRR & RSR to fill
- asm sub DX,5 //
- asm in AL,DX // RECV a character
- asm mov byte ptr c,AL //
- return(c); //
- timerr: //
- printerr(); //
- return(-1); //
- }
- /****************************************************/
- /* Bcrcv does not perform a DSK xmit/rcv handshake! */
- /* IE 2X SPEED! But be careful! */
- /****************************************************/
- unsigned char Bcrcv(int port_no)
- {
- unsigned char c;
- asm mov DX,word ptr port_no // RECV a character
- asm add DX,5 // check LINE_STATUS 0x2FD 0x3FD (+5)
- asm mov BX,4000 // 836 loops is marginal at 4800 baud.
- chkst: // with 33MHz 486
- asm sub bx,1 //
- asm jz timerr //
- asm in AL,DX //
- asm and AL,061h //
- asm cmp AL,061h //
- asm jne chkst // wait for DRR & RSR to fill
- asm sub DX,5 //
- asm in AL,DX //
- asm mov byte ptr c,AL //
- return(c); //
- timerr: //
- printerr(); //
- return(-1); //
- }